#include <stdio.h>
#include <stdint.h>
#include <string.h>

// 协议常量定义
#define PROTO_START_CHAR ':'
#define PROTO_END_CR '\r'
#define PROTO_END_LF '\n'

// 十六进制字符判定
static int is_hex_char(char c) {
	return ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f'));
}

static int hex2byte(const char *p, uint8_t *out) {
	if (!is_hex_char(p[0]) || !is_hex_char(p[1])) return -1;
	int v = 0;
	for (int i = 0; i < 2; i++) {
		char c = p[i];
		v <<= 4;
		if (c >= '0' && c <= '9') v |= (c - '0');
		else if (c >= 'A' && c <= 'F') v |= (c - 'A' + 10);
		else v |= (c - 'a' + 10);
	}
	*out = (uint8_t)v;
	return 0;
}

static const uint8_t *skip_spaces(const uint8_t *p, const uint8_t *end) {
	while (p < end && (*p == ' ' || *p == '\t')) p++;
	return p;
}

// 修复后的协议解析函数
static int parse_protocol_frame(const uint8_t *buf, int len,
						uint8_t *addr, uint8_t *func, uint32_t *data_len,
						const uint8_t **data_ptr, const uint8_t **frame_end) {
	if (len < 9 || buf[0] != PROTO_START_CHAR) return -1;
	const uint8_t *p = buf + 1;
	const uint8_t *end = buf + len;

	printf("DEBUG: 开始解析，起始位置: %td\n", p - buf);
	
	// 跳过空格，提取地址字段（2个ASCII字符）
	p = skip_spaces(p, end);
	printf("DEBUG: 跳过空格后，地址字段位置: %td, 字符: '%c%c'\n", p - buf, p[0], p[1]);
	if (p + 2 > end) return -1;
	
	// 直接提取地址的ASCII值，转换为数字
	if (p[0] < '0' || p[0] > '9' || p[1] < '0' || p[1] > '9') return -1;
	*addr = (p[0] - '0') * 10 + (p[1] - '0');
	p += 2;
	printf("DEBUG: 地址解析成功: %u, 下一位置: %td\n", *addr, p - buf);
	
	// 跳过空格，提取功能码字段（2个ASCII字符）
	p = skip_spaces(p, end);
	printf("DEBUG: 跳过空格后，功能码字段位置: %td, 字符: '%c%c'\n", p - buf, p[0], p[1]);
	if (p + 2 > end) return -1;
	
	// 直接提取功能码的ASCII值，转换为数字
	if (p[0] < '0' || p[0] > '9' || p[1] < '0' || p[1] > '9') return -1;
	*func = (p[0] - '0') * 10 + (p[1] - '0');
	p += 2;
	printf("DEBUG: 功能码解析成功: %u, 下一位置: %td\n", *func, p - buf);
	
	// 跳过空格，提取长度字段（2个ASCII字符）
	p = skip_spaces(p, end);
	printf("DEBUG: 长度字段位置: %td, 字符: '%c%c'\n", p - buf, p[0], p[1]);
	if (p + 2 > end) return -1;
	
	// 直接提取长度的ASCII值，转换为数字（支持十六进制格式）
	uint8_t len_high, len_low;
	
	// 处理高位
	if (p[0] >= '0' && p[0] <= '9') {
		len_high = p[0] - '0';
	} else if (p[0] >= 'A' && p[0] <= 'F') {
		len_high = p[0] - 'A' + 10;
	} else if (p[0] >= 'a' && p[0] <= 'f') {
		len_high = p[0] - 'a' + 10;
	} else {
		return -1;
	}
	
	// 处理低位
	if (p[1] >= '0' && p[1] <= '9') {
		len_low = p[1] - '0';
	} else if (p[1] >= 'A' && p[1] <= 'F') {
		len_low = p[1] - 'A' + 10;
	} else if (p[1] >= 'a' && p[1] <= 'f') {
		len_low = p[1] - 'a' + 10;
	} else {
		return -1;
	}
	
	*data_len = len_high * 16 + len_low;
	p += 2;
	printf("DEBUG: 长度解析成功: %u, 下一位置: %td\n", *data_len, p - buf);
	
	// 跳过空格，定位数据开始位置
	p = skip_spaces(p, end);
	printf("DEBUG: 跳过空格后，数据开始位置: %td\n", p - buf);

	// 数据区从p开始，长度为data_len
	const uint8_t *data_start = p;
	const uint8_t *data_end = p + *data_len;
	
	// 检查数据区域是否超出缓冲区
	if (data_end > end) {
		printf("协议数据区域超出缓冲区: 数据结束位置=%p, 缓冲区结束=%p\n", data_end, end);
		return -1;
	}
	
	// 查找行尾（第一个\r或\n）
	const uint8_t *q = data_end;
	for (const uint8_t *i = data_start; i < end; i++) {
		if (*i == PROTO_END_CR || *i == PROTO_END_LF) {
			q = i;
			break;
		}
	}
	
	printf("DEBUG: 数据区域: 从%td到%td, 行尾位置: %td\n", data_start - buf, data_end - buf, q - buf);
	
	// 设置输出参数
	*data_ptr = data_start;
	*frame_end = q + 1; // 指向\r或\n之后
	return 0;
}

int main() {
	// 测试数据：:00 01 11 20250817134000123\r\n
	uint8_t test_data[] = ":00 01 11 20250817134000123 \r\n";
    //uint8_t test_data[] = ":01 10 0B GET_ALL_DATA \r\n";
    
	int test_len = sizeof(test_data) - 1; // 去掉字符串结尾的\0
	
	printf("测试数据: %s\n", test_data);
	printf("数据长度: %d\n", test_len);
	
	// 显示ASCII数据，特殊字符用转义形式
	printf("ASCII数据: ");
	for (int i = 0; i < test_len; i++) {
		if (test_data[i] >= 32 && test_data[i] <= 126) {
			printf("%c", test_data[i]);
		} else if (test_data[i] == '\r') {
			printf("\\r");
		} else if (test_data[i] == '\n') {
			printf("\\n");
		} else {
			printf("\\x%02X", test_data[i]);
		}
	}
	printf("\n");
	
	uint8_t addr, func;
	uint32_t data_len;
	const uint8_t *data_ptr, *frame_end;
	
	int result = parse_protocol_frame(test_data, test_len, &addr, &func, &data_len, &data_ptr, &frame_end);
	
	if (result == 0) {
		printf("协议解析成功!\n");
		printf("地址: 0x%02X\n", addr);
		printf("功能码: 0x%02X\n", func);
		printf("数据长度: %u\n", data_len);
		printf("数据内容: ");
		for (uint32_t i = 0; i < data_len; i++) {
			printf("%c", data_ptr[i]);
		}
		printf("\n");
		printf("帧结束位置: %td\n", frame_end - test_data);
	} else {
		printf("协议解析失败!\n");
	}
	
	return 0;
} 